/*-----------------------------------------------------------------------------
v7_filter
Created (24.11.2014)
Last modification (1.12.2014)
Version 2.0
v7 filter
-------------------------------------------------------------------------------
//	dkl(n) = (v(n)   - v(n-k)) - (v(n-l) - v(n-k-l))
//	p(n) = p(n-1) + dkl(n), n<=0
//	r(n) = p(n)   + M*dkl(n)
//	s(n) = s(n-1) + r(n),   n<=0
-------------------------------------------------------------------------------
-- SystemVerilog v7_filter
-------------------------------------------------------------------------------*/

module v7_filter 	
(	
	input  wire																reset,	
	input  wire																clk,
//------------------------------------------------------------------------
	input  wire      [SIZE_ADC_DATA - 1: 0]							        input_data,
//------------------------------------------------------------------------
	output reg signed[SIZE_ADC_DATA - 1: 0]									exp2[FP_L + FP_K : 0], 
	
	
//func_DD - func_D with delay 1.
	output reg signed [SIZE_ADC_DATA : 0]									dk, 
	output reg signed [SIZE_ADC_DATA : 0]									dl,
	output reg signed [SIZE_ADC_DATA : 0]									dkl, 
	output reg signed [SIZE_ADC_DATA + 1: 0]								p, 
	output reg signed [SIZE_ADC_DATA + 1: 0]								pp, 
	output reg signed [(SIZE_ADC_DATA + 1)*2: 0]							Mdkl, 
	output reg signed [(SIZE_ADC_DATA + 1)*2 + 1: 0]						r,
	output reg signed [SIZE_ADC_DATA + 3: 0]								s,
    
//func_S always >= 0, output_data always >= 0
	output reg  [(SIZE_ADC_DATA + 3)*2 + 2: 0]								func_S,
	output reg  [(SIZE_ADC_DATA + 3)*2 + 2: 0]								output_data);
//------------------------------------------------------------------------
	import v7_parameters::*;	
	
	always @ (posedge clk or negedge reset)
	begin
		if (!reset)
		begin
                
            for(integer i = 0; i <= FP_L + FP_K; i++)
				exp2[i]													    <= 0;
			
			dk                                                              <= 0;
			dl                                                              <= 0;
			dkl                                                             <= 0;
			p                                                               <= 0;
			pp                                                              <= 0;
			Mdkl															<= 0;
			r																<= 0;
			s																<= 0;
			output_data												       	<= 0;
		end
		else
		begin
			exp2[0]										            	    <= input_data;
			for(integer i=1; i <= FP_L + FP_K; i++)
				exp2[i]													    <= exp2[i-1];	
				
			dk                                                              <= exp2[0] - exp2[FP_K];
			dl                                                              <= exp2[FP_L] - exp2[FP_K + FP_L];
			dkl                                                             <= dk - dl;
			p                                                               <= p + dkl;
			pp                                                              <= p;
			Mdkl															<= FP_M*dkl;
			r																<= pp + Mdkl;
			s																<= s + r;	
			output_data														<= s >>> 7;
						
		end        
	end    
endmodule

